package cn.com.cifi.mars.service.impl;

import java.net.InetAddress;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;

import cn.com.cifi.mars.activemq.PortalMqUtils;
import cn.com.cifi.mars.bean.bo.PortalTodoBo;
import cn.com.cifi.mars.bean.bo.SysLogBO;
import cn.com.cifi.mars.bean.dto.ProjectByStagesDto;
import cn.com.cifi.mars.bean.vo.monitoringConsole.PortalTodoVo;
import cn.com.cifi.mars.bean.vo.sys.rsp.CommonProjectByStagesVo;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.common.redis.RedisTemplateUtil;
import cn.com.cifi.mars.constant.CodeEnum;
import cn.com.cifi.mars.constant.Constants;
import cn.com.cifi.mars.constant.FlowStatusEnum;
import cn.com.cifi.mars.constant.HrOrgTypeEunm;
import cn.com.cifi.mars.constant.IsSuccessEnum;
import cn.com.cifi.mars.constant.LogEventEnum;
import cn.com.cifi.mars.constant.LogSrcEnum;
import cn.com.cifi.mars.constant.LogTypeEnum;
import cn.com.cifi.mars.constant.OperatorTypeEnum;
import cn.com.cifi.mars.constant.TodoStatusEnum;
import cn.com.cifi.mars.constant.TodoTypeCodeEnum;
import cn.com.cifi.mars.entity.PortalTodo;
import cn.com.cifi.mars.entity.PortalTodoTask;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.mapper.mars.PortalTodoMapper;
import cn.com.cifi.mars.mapper.mars.PortalTodoTaskMapper;
import cn.com.cifi.mars.mapper.mars.ProjectByStagesMapper;
import cn.com.cifi.mars.service.CommonService;
import cn.com.cifi.mars.service.IdmUserService;
import cn.com.cifi.mars.service.PortalTodoTaskService;
import cn.com.cifi.mars.service.SysLogService;
import cn.com.cifi.mars.util.DateUtils;
import cn.com.cifi.mars.util.LocalDateTimeUtils;
import cn.com.cifi.mars.util.StrUtils;
import cn.com.cifi.mars.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class CommonServiceImpl implements CommonService{

	@Autowired
	private ProjectByStagesMapper projectByStagesMapper;

	@Autowired
	RedisTemplateUtil redisTemplateUtil;

	@Autowired
	private PortalMqUtils activeMqUtils;
	
	/**
	 * 系统编码,通过调用OA流程引擎生成的流程，一定要和OA的sys-code保持一致,不然无法发待办
	 */
	@Value("${PORTAL_SYSCODE}")
	private String systemCode;
	
	@Value("${wait_sys_code}")
	private String waitSyscode;
	
	/**
	 * 门户待办手机端地址
	 */
	@Value("${mobileUrl}")
	private String mobileUrl;
	
	/**
	 * 门户待办pc端地址
	 */
	@Value("${pcUrl}")
	private String pcUrl;

	/**
	 * IP地址
	 */
	@Value("${ipAddress}")
	private String ipAddress;
	
	@Autowired
	private PortalTodoMapper portalTodoMapper;
	
	@Autowired
	private PortalTodoTaskMapper portalTodoTaskMapper;
	
	@Autowired
	private PortalTodoTaskService portalTodoTaskService;
	
	@Autowired
	private SysLogService sysLogService;
	
	@Autowired
	private IdmUserService idmUserService;
	
	/**
	 * 根据组织机构id查询组织机构信息
	 */
	@Override
	public CommonProjectByStagesVo getOrgList(String regionId, String cityId, String projectId) {
		CommonProjectByStagesVo vo=new CommonProjectByStagesVo();
		String orgid="";
		String type="";
		if(StringUtils.isNotBlank(regionId)) {
			orgid=regionId;
			type="1";
		}else if(StringUtils.isNotBlank(cityId)) {
			orgid=cityId;
			type="2";
		}else if(StringUtils.isNotBlank(projectId)){
			orgid=projectId;
			type="3";
		}
		List<ProjectByStagesDto> regionList=new ArrayList<>();
		List<ProjectByStagesDto> cityList=new ArrayList<>();
		List<ProjectByStagesDto> projectList=new ArrayList<>();
		List<ProjectByStagesDto> stagesList=new ArrayList<>();
		
		List<ProjectByStagesDto>list=projectByStagesMapper.selectStagesAllList(orgid);
		for (ProjectByStagesDto p : list) {
			String hrOrgTypeId=p.getHrOrgTypeId();
			if(hrOrgTypeId.equals(HrOrgTypeEunm.ORG_20.getKey())) {
				regionList.add(p);
			}
			if(hrOrgTypeId.equals(HrOrgTypeEunm.ORG_21.getKey())) {
				cityList.add(p);	
			}
			if(hrOrgTypeId.equals(HrOrgTypeEunm.ORG_31.getKey())) {
				projectList.add(p);
			}
			if(hrOrgTypeId.equals(HrOrgTypeEunm.ORG_23.getKey())) {
				projectList.add(p);
			}
			if(hrOrgTypeId.equals(HrOrgTypeEunm.ORG_32.getKey())) {
				stagesList.add(p);
			}
		}
		if(StringUtils.isNotBlank(type)) {
			if(type.equals("2")) {
				//查询城市公司信息
				ProjectByStagesDto c=projectByStagesMapper.selectByOrgdepid(cityId);
				if(c!=null) {
					//查询区域
					ProjectByStagesDto r=projectByStagesMapper.selectByOrgdepid(c.getParentOrgid());
					regionList.add(r);
				}
			}else if(type.equals("3")) {
				//查询项目信息->直管项目上面只有事业部  没有城市公司
				ProjectByStagesDto p=projectByStagesMapper.selectByOrgdepid(projectId);
				if(p!=null) {
					if(p.getHrOrgTypeId().equals(HrOrgTypeEunm.ORG_31.getKey())) {
						//查询城市公司
						ProjectByStagesDto c=projectByStagesMapper.selectByOrgdepid(p.getParentOrgid());
						cityList.add(c);
						if(c!=null) {
							//查询区域
							ProjectByStagesDto r=projectByStagesMapper.selectByOrgdepid(c.getParentOrgid());
							regionList.add(r);
						}
					}
					if(p.getHrOrgTypeId().equals(HrOrgTypeEunm.ORG_23.getKey())) {
						//查询区域
						ProjectByStagesDto r=projectByStagesMapper.selectByOrgdepid(p.getParentOrgid());
						regionList.add(r);
					}
				}
			}
		}
		vo.setRegionList(regionList);
		vo.setCityList(cityList);
		vo.setProjectList(projectList);
		vo.setStagesList(stagesList);
		return vo;
	}
	
    /**
	 * 发送门户待办消息  发起流程  需要哪些字段传入 可以查看实体类注释
	 * @param owerId 当前账号
	 * @param mobileTaskUrl 移动端地址，钉钉上收到待办时，点击后进入的地址。（可为钉钉应用首页）必传
	 * @param pcTaskUrl PC端地址，门户portal.cifi.com.cn中点击一条待办后进入的地址。必传
	 * @param title 待办的主题 自己定义
	 * @param todoType 任务类型，待办列表中显示在主题前面的中括号中，表示提醒审批人待审批的是什么。如“转交”，“驳回”，“合同审批”等，最多用四个字来总结
	 * @param todoTypeCode 任务类型code [1货值填报、2签约编制。。]  ,枚举TodoTypeCodeEnum
	 * @param versionId 任务关联id [货值\供货\签约版本id]  
	 * @param versionIdType 任务关联id类型 [1货值\2供货\3签约]  ,枚举VersionIdTypeEnum
	 * @param userList 发给多个用户
	 * @return
	 */
	@Override
	public synchronized String start(String owerId,PortalTodoBo doorTodoBo,List<IdmUser> userList) {
         //待办id 
         String instanceId =getInstanceId();
         if(StringUtils.isEmpty(owerId)) {
        	 owerId=waitSyscode;
         }
         //操作类型 1/发起流程 2/流程更新 3/删除代办 4/待办转已办 5/抄送新增 6/抄送处理
         String operatorType=OperatorTypeEnum.START.getKey();
         //流程发起时间(时间标准yyyy-MM-dd HH:mm:ss)24小时制
         String flowStartDate=LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR);
         //流程状态 approving/审批中  delete/删除 cancel/作废 complete/完成   draft/草稿  refuse/拒绝  revoke/撤回
         String flowStatus=FlowStatusEnum.APPROVING.getKey();
         //流程类型（门户流程新建维护时候的流程编码）重要
         String flowType=systemCode;
         //流程类型名 非必填
         String flowTypeName=Constants.FLOW_TYPE_NAME;
         //发起人岗位code，非必填，不传时为主岗
         String positionCode="";	
         //任务开始时间(时间标准yyyy-MM-dd HH:mm:ss)24小时制
         String taskArriveDate=LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR);
         //任务详情,注:为一个数组,其中可以包含多个任务
         List<String> taskList = new ArrayList<>();
         List<PortalTodoTask>todoTaskList=new ArrayList<>();
         doorTodoBo.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl()+instanceId);
         
         for (IdmUser us : userList) {
        	 //任务id 
             String taskId =getTaskId();
        	 JSONObject taskItem = new JSONObject();
             taskItem.put("taskId",taskId);
             taskItem.put("todoType",doorTodoBo.getTodoType());
             taskItem.put("taskApproveId",us.getAlias());
             taskItem.put("taskApproveName",us.getUsercn());
             taskItem.put("mobileTaskUrl",doorTodoBo.getMobileTaskUrl());
             taskItem.put("pcTaskUrl",doorTodoBo.getPcTaskUrl());
             taskItem.put("taskArriveDate",taskArriveDate);
             //添加门户待办任务表
             PortalTodoTask dtt=new PortalTodoTask();
             dtt.setTaskId(taskId);
             dtt.setTodoType(doorTodoBo.getTodoType());
             dtt.setTaskApproveId(us.getAlias());
             dtt.setTaskApproveName(us.getUsercn());
             dtt.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl());
             dtt.setPcTaskUrl(doorTodoBo.getPcTaskUrl());
             dtt.setTaskArriveDate(LocalDateTime.now());	
             dtt.setInstanceId(instanceId);
             todoTaskList.add(dtt);
             taskList.add(taskItem.toJSONString());
		 }
         //主要内容
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("instanceId", instanceId);
         jsonObject.put("systemCode", systemCode);
         jsonObject.put("mobileTaskUrl",doorTodoBo.getMobileTaskUrl());
         jsonObject.put("pcTaskUrl", doorTodoBo.getPcTaskUrl());
         jsonObject.put("owerId", waitSyscode);
         jsonObject.put("operatorType", operatorType);
         jsonObject.put("flowStartDate", flowStartDate);
         jsonObject.put("title", doorTodoBo.getTitle());
         jsonObject.put("flowStatus", flowStatus);
         jsonObject.put("flowType", flowType);
         jsonObject.put("flowTypeName", flowTypeName);
         jsonObject.put("positionCode", positionCode);
         jsonObject.put("taskList", taskList);
      
         String msg = jsonObject.toJSONString();
         saveLog("待办消息","发送门户待办消息 ",msg);
         activeMqUtils.start(instanceId, msg);
         //发送完成后添加到门户待办表中
         PortalTodo dt=new PortalTodo();
         dt.setFlowStartDate(LocalDateTime.now());
         dt.setFlowStatus(flowStatus);
         dt.setInstanceId(instanceId);
         dt.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl());
         dt.setPcTaskUrl(doorTodoBo.getPcTaskUrl());
         dt.setOwerId(owerId);
         dt.setOperatorType(operatorType);
         dt.setTitle(doorTodoBo.getTitle());
         dt.setFlowStatus(flowStatus);
         dt.setFlowType(flowType);
         dt.setFlowTypeName(flowTypeName);
         dt.setPositionCode(positionCode);
         dt.setTodoType(doorTodoBo.getTodoType());
         dt.setTodoTypeCode(doorTodoBo.getTodoTypeCode());
         dt.setTaskArriveDate(LocalDateTime.now());
         //任务关联id [货值\供货\签约版本id]
         dt.setVersionId(doorTodoBo.getVersionId());
         //任务关联id类型 [1货值\2供货\3签约]
         dt.setVersionIdType(doorTodoBo.getVersionIdType());
         //待办事项状态  [0默认 1完成 2删除]
         dt.setTodoStatus(TodoStatusEnum.DEFAULT.getKey());
         dt.setUpdateTime(LocalDateTime.now());
         dt.setContent(doorTodoBo.getContent());
         //待办组织类型 1 旭辉集团 2 区域或事业部 3 城市公司 4 项目 5分期
         dt.setOrgType(doorTodoBo.getOrgType());
         //任务执行人/审批人的账号，
         dt.setTaskApproveId(prepareTaskApproveId(userList));
         //任务执行人/审批人的姓名，
         dt.setTaskApproveName(prepareTaskApproveName(userList));
         //处理人账号
         dt.setHandlePersonId(doorTodoBo.getHandlePersonId());
         //处理人姓名
         dt.setHandlePersonName(doorTodoBo.getHandlePersonName());
         //处理时间
         dt.setHandleTime(doorTodoBo.getHandleTime());
         //集团id
         dt.setGroupId(doorTodoBo.getGroupId());
         //区域或事业部id
         dt.setRegionId(doorTodoBo.getRegionId());
         //城市公司id
         dt.setCityId(doorTodoBo.getCityId());
         //项目id
         dt.setProjectId(doorTodoBo.getProjectId());
         //分期id
         dt.setStagesId(doorTodoBo.getStagesId());
         //添加任务表
         portalTodoTaskService.saveBatch(todoTaskList);
         //添加待办表
         int addDt= portalTodoMapper.insert(dt);
         return instanceId;
	}

	private String prepareTaskApproveName(List<IdmUser> userList) {
		StringBuilder sb = new StringBuilder();
		String squ = "";
		if(CollectionUtils.isNotEmpty(userList)) {
			for(IdmUser user : userList) {
				sb.append(squ).append(user.getUsercn());
				squ = "、";
			}
		}
		return sb.toString();
	}

	private String prepareTaskApproveId(List<IdmUser> userList) {
		StringBuilder sb = new StringBuilder();
		String squ = "";
		if(CollectionUtils.isNotEmpty(userList)) {
			for(IdmUser user : userList) {
				sb.append(squ).append(user.getAlias());
				squ = "、";
			}
		}
		return sb.toString();
	}


	private boolean saveLog(String module,String title,String content) {
		SysLogBO bo = new SysLogBO();
		bo.setEvent(LogEventEnum.TIMERTASK);
    	bo.setSource(LogSrcEnum.SYS);
    	bo.setModule(module);
    	bo.setTitle(title);
    	bo.setContent(content);
    	bo.setType(LogTypeEnum.ONE.getKey());
    	bo.setIsSuccess(IsSuccessEnum.SUCCESS.getKey());
        return sysLogService.add(bo,Constants.SYS);
	}
	
	 public static void main(String[] args) {
         
	        //需要生成几位
	        int n =4;
	        //最终生成的字符串
	        String str ="";
	        for (int i =0; i < n; i++) {
	            str = str + (char)(Math.random()*26+'a');
	        }
	         
	        System.out.println(str);
	    }
	 
	private String randomStr() {
		//需要生成几位
        int n =4;
        //最终生成的字符串
        String str ="";
        for (int i =0; i < n; i++) {
            str = str + (char)(Math.random()*26+'a');
        }
        return str;
	}
	
	/**
	 * 待办实例id 系统编码+当前时间+时间戳
	 * @return
	 */
	public String getInstanceId() {
		String now = LocalDateTimeUtils.formatTime(LocalDateTime.now(), "yyyyMMddHHmmssSSS");
        return systemCode + now + randomStr();
	}
	
	
	/**
	 * 任务id 
	 * @return
	 */
	public String getTaskId() {
		String now = LocalDateTimeUtils.formatTime(LocalDateTime.now(), "yyyyMMddHHmmssSSS");
        return systemCode +"_TASK" + now + randomStr();
	}
	
	/**
	 * 根据待办id和操作类型更新流程信息
	 * @param instanceId 待办id
	 * @param operatorType 操作类型  1/发起流程   2/流程更新   3/删除代办   4/待办转已办  5/抄送新增  6/抄送处理
	 * @return
	 */
	@Override
	public String updatePortalProcess(String instanceId, String operatorType,IdmUser startUser,IdmUser receiveUser) {
		if (operatorType.equals(OperatorTypeEnum.UPDATE.getKey())) {
			// 流程更新
			return processUpdating(instanceId);
		}
		if (operatorType.equals(OperatorTypeEnum.DELETE.getKey())) {
			// 删除待办
			return deleteTodo(instanceId,startUser);
		}
		if (operatorType.equals(OperatorTypeEnum.TRANSFERRED_TO_OFFICE.getKey())) {
			// 待办转已办
			return transferredToOffice(instanceId,startUser);
		}
		if (operatorType.equals(OperatorTypeEnum.CC_ADD.getKey())) {
			// 抄送新增
			return ccAdd(instanceId, startUser, receiveUser);
		}
		if (operatorType.equals(OperatorTypeEnum.CC_HANDLE.getKey())) {
			// 抄送处理
			return ccHandle(instanceId, startUser, receiveUser);
		}
		return null;
	}
	
	/**
	 * 流程更新
	 */
	public String processUpdating(String instanceId) {
		PortalTodo pt=portalTodoMapper.selectById(instanceId);
		if(null==pt){
			throw new MsgException(CodeEnum.PORTAL_TODO_IS_NULL);
		}
		pt.setFlowStatus(FlowStatusEnum.APPROVING.getKey());
		pt.setOperatorType(OperatorTypeEnum.UPDATE.getKey());
		pt.setUpdateTime(LocalDateTime.now());
		//根据待办id 获取门户待办任务表
		List<PortalTodoTask>todoTaskList=portalTodoTaskMapper.selectByInstanceId(instanceId);
		send(pt, OperatorTypeEnum.UPDATE.getKey(),"",todoTaskList);
		int upd=portalTodoMapper.updateById(pt);
		return upd+"";
	}
	
	/**
	 * 删除待办
	 */
	public String deleteTodo(String instanceId,IdmUser handUser) {
		PortalTodo pt=portalTodoMapper.selectById(instanceId);
		if(null==pt){
			throw new MsgException(CodeEnum.PORTAL_TODO_IS_NULL);
		}
		pt.setFlowStatus(FlowStatusEnum.DELETE.getKey());
		pt.setOperatorType(OperatorTypeEnum.DELETE.getKey());
		pt.setUpdateTime(LocalDateTime.now());
	    //待办事项状态  [0默认 1完成 2删除]
	    pt.setTodoStatus(TodoStatusEnum.DELETE.getKey());
		pt.setHandlePersonId(handUser.getAlias());
		pt.setHandlePersonName(handUser.getUsercn());
		pt.setHandleTime(LocalDateTime.now());

	    //根据待办id 获取门户待办任务表
	    String taskIds = getTaskIds(instanceId);
	    JSONObject jsonObject = new JSONObject();
        jsonObject.put("instanceId", instanceId);
        jsonObject.put("systemCode", systemCode);
        jsonObject.put("taskIdList", taskIds);
        jsonObject.put("operatorType", OperatorTypeEnum.DELETE.getKey());
        String msg = jsonObject.toJSONString();
        log.info("采用队列模式,msg:" + msg);
        saveLog("待办消息","删除待办任务",msg);
        //门户生产者发送测试消息
        activeMqUtils.start(pt.getInstanceId(), msg);
		int upd=portalTodoMapper.updateById(pt);
		return upd+"";
	}
	
	private String getTaskIds(String instanceId) {
		List<PortalTodoTask> todoTaskList = portalTodoTaskMapper.selectByInstanceId(instanceId);
		StringBuilder sb = new StringBuilder();
		String squ = "";
		for(PortalTodoTask task : todoTaskList) {
			sb.append(squ).append(task.getTaskId());
			squ= ",";
		}
		return sb.toString();
	}
	
	/**
	 * 待办转已办
	 */
	public String transferredToOffice(String instanceId,IdmUser handUser) {
		PortalTodo pt=portalTodoMapper.selectById(instanceId);
		if(null==pt){
			throw new MsgException(CodeEnum.PORTAL_TODO_IS_NULL);
		}
		//根据待办id 获取门户待办任务表
	  	List<PortalTodoTask> todoTaskList = portalTodoTaskMapper.selectByInstanceId(instanceId);
	  	for(PortalTodoTask task : todoTaskList) {
			//主要内容
	        JSONObject jsonObject = new JSONObject();
	        jsonObject.put("taskId",task.getTaskId());
	        jsonObject.put("todoType", task.getTodoType());
	        jsonObject.put("taskArriveDate", LocalDateTimeUtils.formatTime(task.getTaskArriveDate(), DateUtils.DATE_FULL_STR));
	        jsonObject.put("taskApproveId", task.getTaskApproveId());
	        jsonObject.put("taskApproveName",task.getTaskApproveName());
	        jsonObject.put("mobileTaskUrl", task.getMobileTaskUrl());
	        jsonObject.put("pcTaskUrl", task.getPcTaskUrl());
	        jsonObject.put("instanceId", task.getInstanceId());
	        jsonObject.put("systemCode", systemCode);

	        //待办转已办
	        jsonObject.put("operatorType", OperatorTypeEnum.TRANSFERRED_TO_OFFICE.getKey());
	        jsonObject.put("taskDoneDate", LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR));
	        String msg = jsonObject.toJSONString();
	        log.info("采用队列模式,msg:" + msg);
	        saveLog("待办消息","待办转已办任务",msg);
	        activeMqUtils.start( pt.getInstanceId(), msg);
		}
		
	  	//主任务转为已完成
		pt.setFlowStatus(FlowStatusEnum.COMPLETE.getKey());
		pt.setOperatorType(OperatorTypeEnum.TRANSFERRED_TO_OFFICE.getKey());
		pt.setUpdateTime(LocalDateTime.now());
		//修改处理时间
		pt.setHandleTime(LocalDateTime.now());
		//待办事项状态  [0默认 1完成 2删除]
		pt.setTodoStatus(TodoStatusEnum.COMPLETE.getKey());
		pt.setHandlePersonId(handUser.getAlias());
		pt.setHandlePersonName(handUser.getUsercn());
		pt.setHandleTime(LocalDateTime.now());

		//更新主流程为已完成
		send(pt, OperatorTypeEnum.UPDATE.getKey(),"",null);
		int upd=portalTodoMapper.updateById(pt);
		
		return upd+"";
	}
	
	/**
	 *     抄送新增
	 * @param instanceId
	 * @return
	 */
	public String ccAdd(String instanceId,IdmUser startUser,IdmUser receiveUser) {
		PortalTodo pt=portalTodoMapper.selectById(instanceId);
		if(null==pt){
			throw new MsgException(CodeEnum.PORTAL_TODO_IS_NULL);
		}
		String updateTime=LocalDateTimeUtils.formatTime(pt.getUpdateTime(),DateUtils.DATE_FULL_STR);
		pt.setOperatorType(OperatorTypeEnum.CC_ADD.getKey());
		pt.setUpdateTime(LocalDateTime.now());
		
		sendCcAdd(pt, OperatorTypeEnum.CC_ADD.getKey(), updateTime, startUser, receiveUser, UUIDUtils.create());
		int upd=portalTodoMapper.updateById(pt);
		return upd+"";
	}
	
	/**
	 * 抄送处理
	 * @param instanceId 待办id
	 * @param startUser 抄送发起人
	 * @param receiveUser 抄送接收人
	 * @return
	 */
	public String ccHandle(String instanceId,IdmUser startUser,IdmUser receiveUser) {
		PortalTodo pt=portalTodoMapper.selectById(instanceId);
		if(null==pt){
			throw new MsgException(CodeEnum.PORTAL_TODO_IS_NULL);
		}
		String updateTime=LocalDateTimeUtils.formatTime(pt.getUpdateTime(),DateUtils.DATE_FULL_STR);
		pt.setOperatorType(OperatorTypeEnum.CC_HANDLE.getKey());
		pt.setUpdateTime(LocalDateTime.now());
		
		sendCcAdd(pt, OperatorTypeEnum.CC_HANDLE.getKey(), updateTime, startUser, receiveUser, UUIDUtils.create());
		int upd=portalTodoMapper.updateById(pt);
		return upd+"";
	}
	
	/**
	 * 发送消息
	 * @param pt  
	 * @param operatorType 操作类型
	 * @param taskDoneDate 待办处理时间
	 */
	public void send(PortalTodo pt,String operatorType,String taskDoneDate,List<PortalTodoTask> todoTaskList) {
		 //任务详情,注:为一个数组,其中可以包含多个任务
        List<String> taskList = new ArrayList<>();
        if(null!=todoTaskList) {
        	for (PortalTodoTask todoTask : todoTaskList) {
            	JSONObject taskItem = new JSONObject();
                taskItem.put("taskId",todoTask.getTaskId());
                taskItem.put("todoType",todoTask.getTodoType());
                taskItem.put("taskApproveId",todoTask.getTaskApproveId());
                taskItem.put("taskApproveName",todoTask.getTaskApproveName());
                taskItem.put("mobileTaskUrl",todoTask.getMobileTaskUrl());
                taskItem.put("pcTaskUrl",todoTask.getPcTaskUrl());
                taskItem.put("taskArriveDate",LocalDateTimeUtils.formatTime(todoTask.getTaskArriveDate(), DateUtils.DATE_FULL_STR));
                taskList.add(taskItem.toJSONString());
    		}
        }
        
        //主要内容
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("instanceId", pt.getInstanceId());
        jsonObject.put("systemCode", systemCode);
        jsonObject.put("mobileTaskUrl", pt.getMobileTaskUrl());
        jsonObject.put("pcTaskUrl", pt.getPcTaskUrl());
        jsonObject.put("owerId", waitSyscode);
        jsonObject.put("title", pt.getTitle());
        jsonObject.put("flowStatus", pt.getFlowStatus());
        jsonObject.put("flowType", pt.getFlowType());
        jsonObject.put("flowTypeName", pt.getFlowTypeName());
        jsonObject.put("operatorType", operatorType);
        jsonObject.put("flowStartDate", pt.getFlowStartDate());
        jsonObject.put("positionCode", pt.getPositionCode());
        jsonObject.put("flowStartDate", LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR));
        jsonObject.put("taskList", taskList);
        String msg = jsonObject.toJSONString();
        log.info("采用队列模式,msg:" + msg);
        saveLog("待办消息",operatorType+"待办消息流程",msg);
        //门户生产者发送测试消息
        activeMqUtils.start( pt.getInstanceId(), msg);
	}

	
	/**
	 * 发送抄送消息
	 * @param pt 门户待办
	 * @param operatorType 操作类型
	 * @param taskArriveDate 抄送到达时间
	 * @param startUser 抄送发起人
	 * @param receiveUser 抄送接受人
	 * @param callyId 抄送id
	 */
	public void sendCcAdd(PortalTodo pt,String operatorType,String taskArriveDate,IdmUser startUser,IdmUser receiveUser,
			String callyId) {
        //主要内容
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("instanceId", pt.getInstanceId());
        jsonObject.put("systemCode", systemCode);
        jsonObject.put("mobileTaskUrl", pt.getMobileTaskUrl());
        jsonObject.put("pcTaskUrl", pt.getPcTaskUrl());
        jsonObject.put("owerId", pt.getOwerId());
        jsonObject.put("operatorType", operatorType);
        jsonObject.put("flowStartDate", pt.getFlowStartDate());
        jsonObject.put("title", pt.getTitle());
        jsonObject.put("flowStatus", pt.getFlowStatus());
        jsonObject.put("flowType", pt.getFlowType());
        jsonObject.put("flowTypeName", pt.getFlowTypeName());
        jsonObject.put("positionCode", pt.getPositionCode());
        //抄送到达时间
        jsonObject.put("taskArriveDate", taskArriveDate);
        //抄送发起人
        jsonObject.put("callyStartId", startUser.getAlias());
        //抄送发起人名
        jsonObject.put("callyStartName", startUser.getUsercn());
        //抄送接收人
        jsonObject.put("callyReceiveId", receiveUser.getAlias());
        //抄送接受人名
        jsonObject.put("callyReceiveName", receiveUser.getUsercn());
        //抄送id
        jsonObject.put("callyId", callyId);
        String msg = jsonObject.toJSONString();
        log.info("发送抄送消息,msg:" + msg);
        //门户生产者发送测试消息
        
        activeMqUtils.start(pt.getInstanceId(), msg);
	}

	/**
	 * 发送门户待办消息  发起流程
	 * @param owerId 当前账号
	 * @param doorTodoBo 代办内容
	 * @param userList 发给多个用户
	 * @return
	 */
	@Override
	public synchronized String startV2(String owerId, PortalTodoBo doorTodoBo, List<IdmUser> userList) {
		// 待办id
		String instanceId = getInstanceId();
		if (StringUtils.isEmpty(owerId)) {
			owerId = waitSyscode;
		}
		// 操作类型 1/发起流程 2/流程更新 3/删除代办 4/待办转已办 5/抄送新增 6/抄送处理
		String operatorType = OperatorTypeEnum.START.getKey();
		// 流程发起时间(时间标准yyyy-MM-dd HH:mm:ss)24小时制
		String flowStartDate = LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR);
		// 流程状态 approving/审批中 delete/删除 cancel/作废 complete/完成 draft/草稿 refuse/拒绝
		// revoke/撤回
		String flowStatus = FlowStatusEnum.APPROVING.getKey();
		// 流程类型（门户流程新建维护时候的流程编码）重要
		String flowType = systemCode;
		// 流程类型名 非必填
		String flowTypeName = Constants.FLOW_TYPE_NAME;
		// 发起人岗位code，非必填，不传时为主岗
		String positionCode = "";
		// 任务开始时间(时间标准yyyy-MM-dd HH:mm:ss)24小时制
		String taskArriveDate =LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR);
		// 任务详情,注:为一个数组,其中可以包含多个任务
		List<String> taskList = new ArrayList<>();
		List<PortalTodoTask> todoTaskList = new ArrayList<>();
		doorTodoBo.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl() + instanceId);
		doorTodoBo.setPcTaskUrl(doorTodoBo.getPcTaskUrl() + instanceId);
		//负责人ids
		String taskApproveIds="";
		//负责人名称s
		String taskApproveNames="";
		
		for (IdmUser us : userList) {
			// 任务id
			String taskId = getTaskId();
			JSONObject taskItem = new JSONObject();
			taskItem.put("taskId", taskId);
			taskItem.put("todoType", doorTodoBo.getTodoType());
			taskItem.put("taskApproveId", us.getAlias());
			taskItem.put("taskApproveName", us.getUsercn());
			taskItem.put("mobileTaskUrl", doorTodoBo.getMobileTaskUrl());
			taskItem.put("pcTaskUrl", doorTodoBo.getPcTaskUrl());
			taskItem.put("taskArriveDate", taskArriveDate);
			
			if(StringUtils.isNotEmpty(taskApproveIds)) {
				taskApproveIds=taskApproveIds+"、"+us.getAlias();
				taskApproveNames=taskApproveNames+"、"+us.getUsercn();
			}else {
				taskApproveIds=us.getAlias();
				taskApproveNames=us.getUsercn();
			}
			
			// 添加门户待办任务表
			PortalTodoTask dtt = new PortalTodoTask();
			dtt.setTaskId(taskId);
			dtt.setTodoType(doorTodoBo.getTodoType());
			dtt.setTaskApproveId(us.getAlias());
			dtt.setTaskApproveName(us.getUsercn());
			dtt.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl());
			dtt.setPcTaskUrl(doorTodoBo.getPcTaskUrl());
			dtt.setTaskArriveDate(LocalDateTime.now());
			dtt.setInstanceId(instanceId);
			todoTaskList.add(dtt);
			taskList.add(taskItem.toJSONString());
		}
		// 主要内容
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("instanceId", instanceId);
		jsonObject.put("systemCode", systemCode);
		jsonObject.put("mobileTaskUrl", doorTodoBo.getMobileTaskUrl());
		jsonObject.put("pcTaskUrl", doorTodoBo.getPcTaskUrl());
		jsonObject.put("owerId", waitSyscode);
		jsonObject.put("operatorType", operatorType);
		jsonObject.put("flowStartDate", flowStartDate);
		jsonObject.put("title", doorTodoBo.getTitle());
		jsonObject.put("flowStatus", flowStatus);
		jsonObject.put("flowType", flowType);
		jsonObject.put("flowTypeName", flowTypeName);
		jsonObject.put("positionCode", positionCode);
		jsonObject.put("taskList", taskList);

		String msg = jsonObject.toJSONString();
		log.info("采用队列模式,msg:" + msg);

		activeMqUtils.start(instanceId, msg);

		saveLog("待办消息", "发送门户待办消息 ", msg);
		// 发送完成后添加到门户待办表中
		PortalTodo dt = new PortalTodo();
		dt.setFlowStartDate(LocalDateTime.now());
		dt.setFlowStatus(flowStatus);
		dt.setInstanceId(instanceId);
		dt.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl());
		dt.setPcTaskUrl(doorTodoBo.getPcTaskUrl());
		dt.setOwerId(owerId);
		dt.setOperatorType(operatorType);
		dt.setTitle(doorTodoBo.getTitle());
		dt.setFlowStatus(flowStatus);
		dt.setFlowType(flowType);
		dt.setFlowTypeName(flowTypeName);
		dt.setPositionCode(positionCode);
		dt.setTodoType(doorTodoBo.getTodoType());
		dt.setTodoTypeCode(doorTodoBo.getTodoTypeCode());
		dt.setTaskArriveDate(LocalDateTime.now());
		// 任务关联id [货值\供货\签约版本id]
		dt.setVersionId(doorTodoBo.getVersionId());
		// 任务关联id类型 [1货值\2供货\3签约]
		dt.setVersionIdType(doorTodoBo.getVersionIdType());
		// 待办事项状态 [0默认 1完成 2删除]
		dt.setTodoStatus(TodoStatusEnum.DEFAULT.getKey());
		dt.setUpdateTime(LocalDateTime.now());
		dt.setContent(doorTodoBo.getContent());
		// 待办组织类型 1 旭辉集团 2 区域或事业部 3 城市公司 4 项目 5分期
		dt.setOrgType(doorTodoBo.getOrgType());
		// 处理人账号
		dt.setHandlePersonId(doorTodoBo.getHandlePersonId());
		// 处理人姓名
		dt.setHandlePersonName(doorTodoBo.getHandlePersonName());
		// 处理时间
		dt.setHandleTime(doorTodoBo.getHandleTime());
		// 集团id
		dt.setGroupId(doorTodoBo.getGroupId());
		// 区域或事业部id
		dt.setRegionId(doorTodoBo.getRegionId());
		// 城市公司id
		dt.setCityId(doorTodoBo.getCityId());
		// 项目id
		dt.setProjectId(doorTodoBo.getProjectId());
		// 分期id
		dt.setStagesId(doorTodoBo.getStagesId());
		dt.setTaskApproveId(taskApproveIds);
		dt.setTaskApproveName(taskApproveNames);
		// 添加任务表
		portalTodoTaskService.saveBatch(todoTaskList);
		// 添加待办表
		int addDt = portalTodoMapper.insert(dt);
		return instanceId;
	}

	@Override
	public List<PortalTodoVo> getToDoInfo(String todoTypeCode, String projectId, String instanceId) {
		return portalTodoMapper.selectToDoInfo(todoTypeCode,projectId,instanceId);
	}

	@Override
	public void cleanTodo(String todoTypeCode, String operatorType, String projectId, String instanceId,IdmUser user) {
		if(user == null) {
			user = getSysUser();
		}
		if(StrUtils.isNotEmpty(operatorType) && operatorType.equals(OperatorTypeEnum.DELETE.getKey())) {
			if(StrUtils.isNotEmpty(instanceId)) {
				//清除该实例待办
				PortalTodo pt = portalTodoMapper.selectById(instanceId);
				if(null != pt){
					String taskApproveId  = pt.getTaskApproveId();
					String typeCode = pt.getTodoTypeCode();
					if(StrUtils.isNotEmpty(typeCode) && typeCode.equals(TodoTypeCodeEnum.EARLY_WARNING.getKey())) {
						user = getHandleUser(taskApproveId,user);
					}
				}
				if(user == null) {
					user = getSysUser();
				}
				deleteTodo(instanceId,user);
			}else if(StrUtils.isNotEmpty(todoTypeCode)) {
				user = getSysUser();
				//清除该类型下所有待办
				List<PortalTodo> todoList = portalTodoMapper.selectByTodoTypeCode(todoTypeCode,TodoStatusEnum.DEFAULT.getKey());
				if(CollectionUtils.isNotEmpty(todoList)) {
					for(PortalTodo todoObj : todoList) {
						String instId = todoObj.getInstanceId();
						deleteTodo(instId,user);
					}
				}
			}else if(StrUtils.isNotEmpty(projectId)) {
				user = getSysUser();
				//清除该项目下所有待办
				List<PortalTodo> todoList = portalTodoMapper.selectProjectId(projectId,TodoStatusEnum.DEFAULT.getKey());
				if(CollectionUtils.isNotEmpty(todoList)) {
					for(PortalTodo todoObj : todoList) {
						String instId = todoObj.getInstanceId();
						deleteTodo(instId,user);
					}
				}
			}
		}else if (StrUtils.isNotEmpty(operatorType) && operatorType.equals(OperatorTypeEnum.TRANSFERRED_TO_OFFICE.getKey())) {
			if(StrUtils.isNotEmpty(instanceId)) {
				//该实例待办转已办
				PortalTodo pt = portalTodoMapper.selectById(instanceId);
				if(null != pt){
					String taskApproveId  = pt.getTaskApproveId();
					String typeCode = pt.getTodoTypeCode();
//					if(StrUtils.isNotEmpty(typeCode) && typeCode.equals(TodoTypeCodeEnum.EARLY_WARNING.getKey())) {
						user = getHandleUser(taskApproveId,user);
//					}
				}
				if(user == null) {
					user = getSysUser();
				}
				transferredToOffice(instanceId,user);
			}else if(StrUtils.isNotEmpty(todoTypeCode)) {
				user = getSysUser();
				//该类型下所有待办转已办
				List<PortalTodo> todoList = portalTodoMapper.selectByTodoTypeCode(todoTypeCode,TodoStatusEnum.DEFAULT.getKey());
				if(CollectionUtils.isNotEmpty(todoList)) {
					for(PortalTodo todoObj : todoList) {
						String instId = todoObj.getInstanceId();
						transferredToOffice(instId,user);
					}
				}
				
			}else if(StrUtils.isNotEmpty(projectId)) {
				user = getSysUser();
				//该项目下所有待办转已办
				List<PortalTodo> todoList = portalTodoMapper.selectProjectId(projectId,TodoStatusEnum.DEFAULT.getKey());
				if(CollectionUtils.isNotEmpty(todoList)) {
					for(PortalTodo todoObj : todoList) {
						String instId = todoObj.getInstanceId();
						transferredToOffice(instId,user);
					}
				}
			}
		}
	}

	private IdmUser getSysUser() {
		IdmUser user=new IdmUser();;
		user.setAlias(Constants.SYS);
		user.setUsercn(Constants.SYS_NAME);
		return user;
	}
	
	private IdmUser getHandleUser(String taskApproveId,IdmUser user) {
		if(StrUtils.isNotEmpty(taskApproveId)) {
			if(taskApproveId.indexOf(",") > 0) {
				return idmUserService.getByAlias(taskApproveId.split(",")[0]);
			}else {
				return idmUserService.getByAlias(taskApproveId);
			}
		}
		return user;
	}

	/**
	 * 发送消息代办
	 * @param todoBo
	 * @param userList
	 * @return
	 */
	@Override
	public List<String> sendMessagePortalTodo(PortalTodoBo todoBo, List<IdmUser> userList){
		List<String> instanceIdList = new ArrayList<>();
		for (IdmUser idmUser : userList){
			//门户待办id
			String instanceId = sendMessagePortalTodoByUser(Constants.SYS, todoBo,idmUser);
			instanceIdList.add(instanceId);
		}
		return instanceIdList;
	}

	/**
	 * 一个人发送门户待办
	 * @param owerId
	 * @param doorTodoBo
	 * @param us
	 * @return
	 */
	@Override
	public synchronized String sendMessagePortalTodoByUser(String owerId, PortalTodoBo doorTodoBo, IdmUser us) {
		String instanceId = getInstanceId();
		if (StringUtils.isEmpty(owerId)) {
			owerId = waitSyscode;
		}
		//移动端地址，钉钉上收到待办时，点击后进入的地址。必传
		doorTodoBo.setMobileTaskUrl(mobileUrl+ instanceId);
		//PC端地址，门户网站中点击一条待办后进入的地址。必传
		doorTodoBo.setPcTaskUrl(pcUrl+ instanceId);
		// 操作类型 1/发起流程 2/流程更新 3/删除代办 4/待办转已办 5/抄送新增 6/抄送处理
		String operatorType = OperatorTypeEnum.START.getKey();
		// 流程发起时间(时间标准yyyy-MM-dd HH:mm:ss)24小时制
		String flowStartDate = LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR);
		// 流程状态 approving/审批中 delete/删除 cancel/作废  complete/完成  draft/草稿  refuse/拒绝  revoke/撤回
		String flowStatus = FlowStatusEnum.APPROVING.getKey();
		// 流程类型（门户流程新建维护时候的流程编码）重要
		String flowType = systemCode;
		// 流程类型名 非必填
		String flowTypeName = Constants.FLOW_TYPE_NAME;
		// 发起人岗位code，非必填，不传时为主岗
		String positionCode = "";
		// 任务开始时间(时间标准yyyy-MM-dd HH:mm:ss)24小时制
		String taskArriveDate = LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR);
		// 任务详情,注:为一个数组,其中可以包含多个任务
		List<String> taskList = new ArrayList<>();
		List<PortalTodoTask> todoTaskList = new ArrayList<>();
		// 任务id
		String taskId = getTaskId();
		JSONObject taskItem = new JSONObject();
		taskItem.put("taskId", taskId);
		taskItem.put("todoType", doorTodoBo.getTodoType());
		taskItem.put("taskApproveId", us.getAlias());
		taskItem.put("taskApproveName", us.getUsercn());
		taskItem.put("mobileTaskUrl", doorTodoBo.getMobileTaskUrl());
		taskItem.put("pcTaskUrl", doorTodoBo.getPcTaskUrl());
		taskItem.put("taskArriveDate", taskArriveDate);

		// 添加门户待办任务表
		PortalTodoTask dtt = new PortalTodoTask();
		dtt.setTaskId(taskId);
		dtt.setTodoType(doorTodoBo.getTodoType());
		dtt.setTaskApproveId(us.getAlias());
		dtt.setTaskApproveName(us.getUsercn());
		dtt.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl());
		dtt.setPcTaskUrl(doorTodoBo.getPcTaskUrl());
		dtt.setTaskArriveDate(LocalDateTime.now());
		dtt.setInstanceId(instanceId);
		todoTaskList.add(dtt);
		taskList.add(taskItem.toJSONString());
		
		// 主要内容
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("instanceId", instanceId);
		jsonObject.put("systemCode", systemCode);
		jsonObject.put("mobileTaskUrl", doorTodoBo.getMobileTaskUrl());
		jsonObject.put("pcTaskUrl", doorTodoBo.getPcTaskUrl());
		jsonObject.put("owerId", waitSyscode);
		jsonObject.put("operatorType", operatorType);
		jsonObject.put("flowStartDate", flowStartDate);
		jsonObject.put("title", doorTodoBo.getTitle());
		jsonObject.put("flowStatus", flowStatus);
		jsonObject.put("flowType", flowType);
		jsonObject.put("flowTypeName", flowTypeName);
		jsonObject.put("positionCode", positionCode);
		jsonObject.put("taskList", taskList);

		String msg = jsonObject.toJSONString();
		log.info("######发送待办消息 参数：" + msg);
		activeMqUtils.start(instanceId, msg);
		saveLog("待办消息", "发送门户待办消息 ", msg);
		// 发送完成后添加到门户待办表中
		PortalTodo dt = new PortalTodo();
		dt.setFlowStartDate(LocalDateTime.now());
		dt.setFlowStatus(flowStatus);
		dt.setInstanceId(instanceId);
		dt.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl());
		dt.setPcTaskUrl(doorTodoBo.getPcTaskUrl());
		dt.setOwerId(owerId);
		dt.setOperatorType(operatorType);
		dt.setTitle(doorTodoBo.getTitle());
		dt.setFlowStatus(flowStatus);
		dt.setFlowType(flowType);
		dt.setFlowTypeName(flowTypeName);
		dt.setPositionCode(positionCode);
		dt.setTodoType(doorTodoBo.getTodoType());
		dt.setTodoTypeCode(doorTodoBo.getTodoTypeCode());
		dt.setTaskArriveDate(LocalDateTime.now());
		dt.setVersionId(doorTodoBo.getVersionId());
		dt.setVersionIdType(doorTodoBo.getVersionIdType());
		// 待办事项状态 [0默认 1完成 2删除]
		dt.setTodoStatus(TodoStatusEnum.DEFAULT.getKey());
		dt.setUpdateTime(LocalDateTime.now());
		dt.setContent(doorTodoBo.getContent());
		// 待办组织类型 1 旭辉集团 2 区域或事业部 3 城市公司 4 项目 5分期
		dt.setOrgType(doorTodoBo.getOrgType());
		dt.setHandlePersonId(doorTodoBo.getHandlePersonId());
		dt.setHandlePersonName(doorTodoBo.getHandlePersonName());
		dt.setHandleTime(doorTodoBo.getHandleTime());
		dt.setGroupId(doorTodoBo.getGroupId());
		dt.setRegionId(doorTodoBo.getRegionId());
		dt.setCityId(doorTodoBo.getCityId());
		dt.setProjectId(doorTodoBo.getProjectId());
		dt.setStagesId(doorTodoBo.getStagesId());
		dt.setTaskApproveId(us.getAlias());
		dt.setTaskApproveName(us.getUsercn());
		// 添加任务表
		portalTodoTaskService.saveBatch(todoTaskList);
		// 添加待办表
		int addDt = portalTodoMapper.insert(dt);
		return instanceId;
	}
	
	@Value("${warning_supervise_todo_pc_url}")
	private  String warningSuperviseTodoPcUrl;
	
	@Value("${warning_supervise_todo_app_url}")
	private String  warningSuperviseTodoAppUrl;
	
	@Override
	public String sendPortalTodo(String owerId, PortalTodoBo doorTodoBo, IdmUser us) {
		String instanceId = getInstanceId();
		if (StringUtils.isEmpty(owerId)) {
			owerId = waitSyscode;
		}
		//移动端地址，钉钉上收到待办时，点击后进入的地址。必传
		doorTodoBo.setMobileTaskUrl(warningSuperviseTodoPcUrl+ instanceId);
		//PC端地址，门户网站中点击一条待办后进入的地址。必传
		doorTodoBo.setPcTaskUrl(warningSuperviseTodoPcUrl+ instanceId);
		// 操作类型 1/发起流程 2/流程更新 3/删除代办 4/待办转已办 5/抄送新增 6/抄送处理
		String operatorType = OperatorTypeEnum.START.getKey();
		// 流程发起时间(时间标准yyyy-MM-dd HH:mm:ss)24小时制
		String flowStartDate = LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR);
		// 流程状态 approving/审批中 delete/删除 cancel/作废  complete/完成  draft/草稿  refuse/拒绝  revoke/撤回
		String flowStatus = FlowStatusEnum.APPROVING.getKey();
		// 流程类型（门户流程新建维护时候的流程编码）重要
		String flowType = systemCode;
		// 流程类型名 非必填
		String flowTypeName = Constants.FLOW_TYPE_NAME;
		// 发起人岗位code，非必填，不传时为主岗
		String positionCode = "";
		// 任务开始时间(时间标准yyyy-MM-dd HH:mm:ss)24小时制
		String taskArriveDate = LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR);
		// 任务详情,注:为一个数组,其中可以包含多个任务
		List<String> taskList = new ArrayList<>();
		List<PortalTodoTask> todoTaskList = new ArrayList<>();
		// 任务id
		String taskId = getTaskId();
		JSONObject taskItem = new JSONObject();
		taskItem.put("taskId", taskId);
		taskItem.put("todoType", doorTodoBo.getTodoType());
		taskItem.put("taskApproveId", us.getAlias());
		taskItem.put("taskApproveName", us.getUsercn());
		taskItem.put("mobileTaskUrl", doorTodoBo.getMobileTaskUrl());
		taskItem.put("pcTaskUrl", doorTodoBo.getPcTaskUrl());
		taskItem.put("taskArriveDate", taskArriveDate);

		// 添加门户待办任务表
		PortalTodoTask dtt = new PortalTodoTask();
		dtt.setTaskId(taskId);
		dtt.setTodoType(doorTodoBo.getTodoType());
		dtt.setTaskApproveId(us.getAlias());
		dtt.setTaskApproveName(us.getUsercn());
		dtt.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl());
		dtt.setPcTaskUrl(doorTodoBo.getPcTaskUrl());
		dtt.setTaskArriveDate(LocalDateTime.now());
		dtt.setInstanceId(instanceId);
		todoTaskList.add(dtt);
		taskList.add(taskItem.toJSONString());
		
		// 发送完成后添加到门户待办表中
		PortalTodo dt = new PortalTodo();
		dt.setFlowStartDate(LocalDateTime.now());
		dt.setFlowStatus(flowStatus);
		dt.setInstanceId(instanceId);
		dt.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl());
		dt.setPcTaskUrl(doorTodoBo.getPcTaskUrl());
		dt.setOwerId(owerId);
		dt.setOperatorType(operatorType);
		dt.setTitle(doorTodoBo.getTitle());
		dt.setFlowStatus(flowStatus);
		dt.setFlowType(flowType);
		dt.setFlowTypeName(flowTypeName);
		dt.setPositionCode(positionCode);
		dt.setTodoType(doorTodoBo.getTodoType());
		dt.setTodoTypeCode(doorTodoBo.getTodoTypeCode());
		dt.setTaskArriveDate(LocalDateTime.now());
		dt.setVersionId(doorTodoBo.getVersionId());
		dt.setVersionIdType(doorTodoBo.getVersionIdType());
		// 待办事项状态 [0默认 1完成 2删除]
		dt.setTodoStatus(TodoStatusEnum.DEFAULT.getKey());
		dt.setUpdateTime(LocalDateTime.now());
		dt.setContent(doorTodoBo.getContent());
		// 待办组织类型 1 旭辉集团 2 区域或事业部 3 城市公司 4 项目 5分期
		dt.setOrgType(doorTodoBo.getOrgType());
		dt.setHandlePersonId(doorTodoBo.getHandlePersonId());
		dt.setHandlePersonName(doorTodoBo.getHandlePersonName());
		dt.setHandleTime(doorTodoBo.getHandleTime());
		dt.setGroupId(doorTodoBo.getGroupId());
		dt.setRegionId(doorTodoBo.getRegionId());
		dt.setCityId(doorTodoBo.getCityId());
		dt.setProjectId(doorTodoBo.getProjectId());
		dt.setStagesId(doorTodoBo.getStagesId());
		dt.setTaskApproveId(us.getAlias());
		dt.setTaskApproveName(us.getUsercn());
		// 添加任务表
		portalTodoTaskService.saveBatch(todoTaskList);
		// 添加待办表
		int addDt = portalTodoMapper.insert(dt);
		
		// 主要内容
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("instanceId", instanceId);
		jsonObject.put("systemCode", systemCode);
		jsonObject.put("mobileTaskUrl", doorTodoBo.getMobileTaskUrl());
		jsonObject.put("pcTaskUrl", doorTodoBo.getPcTaskUrl());
		jsonObject.put("owerId", waitSyscode);
		jsonObject.put("operatorType", operatorType);
		jsonObject.put("flowStartDate", flowStartDate);
		jsonObject.put("title", doorTodoBo.getTitle());
		jsonObject.put("flowStatus", flowStatus);
		jsonObject.put("flowType", flowType);
		jsonObject.put("flowTypeName", flowTypeName);
		jsonObject.put("positionCode", positionCode);
		jsonObject.put("taskList", taskList);

		String msg = jsonObject.toJSONString();
		log.info("######发送待办消息 参数：" + msg);
		activeMqUtils.start(instanceId, msg);
		saveLog("待办消息", "发送门户待办消息 ", msg);
		return instanceId;
	}
	
	@Override
	public String sendTodoMsg(String owerId,PortalTodoBo doorTodoBo,List<IdmUser> userList) {
         String instanceId =getInstanceId();
         if(StringUtils.isEmpty(owerId)) {
        	 owerId=waitSyscode;
         }
         //操作类型 1/发起流程 2/流程更新 3/删除代办 4/待办转已办 5/抄送新增 6/抄送处理
         String operatorType=OperatorTypeEnum.START.getKey();
         //流程发起时间(时间标准yyyy-MM-dd HH:mm:ss)24小时制
         String flowStartDate=LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR);
         //流程状态 approving/审批中  delete/删除 cancel/作废 complete/完成   draft/草稿  refuse/拒绝  revoke/撤回
         String flowStatus=FlowStatusEnum.APPROVING.getKey();
         //流程类型（门户流程新建维护时候的流程编码）重要
         String flowType=systemCode;
         //流程类型名 非必填
         String flowTypeName=Constants.FLOW_TYPE_NAME;
         //发起人岗位code，非必填，不传时为主岗
         String positionCode="";	
         //任务开始时间(时间标准yyyy-MM-dd HH:mm:ss)24小时制
         String taskArriveDate=LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR);
         //任务详情,注:为一个数组,其中可以包含多个任务
         List<String> taskList = new ArrayList<>();
         List<PortalTodoTask>todoTaskList=new ArrayList<>();
         doorTodoBo.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl());
         doorTodoBo.setPcTaskUrl(doorTodoBo.getPcTaskUrl()+instanceId);
         for (IdmUser us : userList) {
             String taskId =getTaskId();
        	 JSONObject taskItem = new JSONObject();
             taskItem.put("taskId",taskId);
             taskItem.put("todoType",doorTodoBo.getTodoType());
             taskItem.put("taskApproveId",us.getAlias());
             taskItem.put("taskApproveName",us.getUsercn());
             taskItem.put("mobileTaskUrl",doorTodoBo.getMobileTaskUrl()+"&userId="+us.getAlias());
             taskItem.put("pcTaskUrl",doorTodoBo.getPcTaskUrl()+"&userId="+us.getAlias());
             taskItem.put("taskArriveDate",taskArriveDate);
             //添加门户待办任务表
             PortalTodoTask dtt=new PortalTodoTask();
             dtt.setTaskId(taskId);
             dtt.setTodoType(doorTodoBo.getTodoType());
             dtt.setTaskApproveId(us.getAlias());
             dtt.setTaskApproveName(us.getUsercn());
             dtt.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl()+"&userId="+us.getAlias());
             dtt.setPcTaskUrl(doorTodoBo.getPcTaskUrl()+"&userId="+us.getAlias());
             dtt.setTaskArriveDate(LocalDateTime.now());	
             dtt.setInstanceId(instanceId);
             todoTaskList.add(dtt);
             taskList.add(taskItem.toJSONString());
		 }
         
        //发送完成后添加到门户待办表中
         PortalTodo dt=new PortalTodo();
         dt.setFlowStartDate(LocalDateTime.now());
         dt.setFlowStatus(flowStatus);
         dt.setInstanceId(instanceId);
         dt.setMobileTaskUrl(doorTodoBo.getMobileTaskUrl());
         dt.setPcTaskUrl(doorTodoBo.getPcTaskUrl());
         dt.setOwerId(owerId);
         dt.setOperatorType(operatorType);
         dt.setTitle(doorTodoBo.getTitle());
         dt.setFlowStatus(flowStatus);
         dt.setFlowType(flowType);
         dt.setFlowTypeName(flowTypeName);
         dt.setPositionCode(positionCode);
         dt.setTodoType(doorTodoBo.getTodoType());
         dt.setTodoTypeCode(doorTodoBo.getTodoTypeCode());
         dt.setTaskArriveDate(LocalDateTime.now());
         //任务关联id [货值\供货\签约版本id]
         dt.setVersionId(doorTodoBo.getVersionId());
         //任务关联id类型 [1货值\2供货\3签约]
         dt.setVersionIdType(doorTodoBo.getVersionIdType());
         //待办事项状态  [0默认 1完成 2删除]
         dt.setTodoStatus(TodoStatusEnum.DEFAULT.getKey());
         dt.setUpdateTime(LocalDateTime.now());
         dt.setContent(doorTodoBo.getContent());
         //待办组织类型 1 旭辉集团 2 区域或事业部 3 城市公司 4 项目 5分期
         dt.setOrgType(doorTodoBo.getOrgType());
         //任务执行人/审批人的账号，
         dt.setTaskApproveId(prepareTaskApproveId(userList));
         //任务执行人/审批人的姓名，
         dt.setTaskApproveName(prepareTaskApproveName(userList));
         //处理人账号
         dt.setHandlePersonId(doorTodoBo.getHandlePersonId());
         //处理人姓名
         dt.setHandlePersonName(doorTodoBo.getHandlePersonName());
         //处理时间
         dt.setHandleTime(doorTodoBo.getHandleTime());
         //集团id
         dt.setGroupId(doorTodoBo.getGroupId());
         //区域或事业部id
         dt.setRegionId(doorTodoBo.getRegionId());
         //城市公司id
         dt.setCityId(doorTodoBo.getCityId());
         //项目id
         dt.setProjectId(doorTodoBo.getProjectId());
         //分期id
         dt.setStagesId(doorTodoBo.getStagesId());
         //添加任务表
         portalTodoTaskService.saveBatch(todoTaskList);
         //添加待办表
         int addDt= portalTodoMapper.insert(dt);
         
         //主要内容
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("instanceId", instanceId);
         jsonObject.put("systemCode", systemCode);
         jsonObject.put("mobileTaskUrl",doorTodoBo.getMobileTaskUrl());
         jsonObject.put("pcTaskUrl", doorTodoBo.getPcTaskUrl());
         jsonObject.put("owerId", waitSyscode);
         jsonObject.put("operatorType", operatorType);
         jsonObject.put("flowStartDate", flowStartDate);
         jsonObject.put("title", doorTodoBo.getTitle());
         jsonObject.put("flowStatus", flowStatus);
         jsonObject.put("flowType", flowType);
         jsonObject.put("flowTypeName", flowTypeName);
         jsonObject.put("positionCode", positionCode);
         jsonObject.put("taskList", taskList);
      
         String msg = jsonObject.toJSONString();
         log.info("采用队列模式,msg:" + msg);
        
         activeMqUtils.start(instanceId, msg);

         saveLog("待办消息","发送门户待办消息 ",msg);
         
         return instanceId;
	}
	

	@Override
	public boolean isAppointIP() {
		boolean isAppointIP = false;
		List<String> uatIps = Arrays.asList("10.129.37.106","10.129.37.107");
		try{
			String hostAddress = InetAddress.getLocalHost().getHostAddress();
			log.info("############    isAppointIP   hostAddress:"+hostAddress);
			if(uatIps.contains(hostAddress)) {
				isAppointIP = true;
			}
			if (hostAddress != null && ipAddress.equals(hostAddress)){
				isAppointIP = true;
			}
		}catch (Exception e){
			log.error("############    isAppointIP   error:"+e.getMessage(), e);
		}
		return isAppointIP;
	}

}
